home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
ASTRONOM
/
H139.ZIP
/
UI101.ZIP
/
IO
/
GR
/
GR_IBMPC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-04
|
34KB
|
1,456 lines
/****************************************************************
gr_ibmpc.c Implementation of Bywater Graphics Interface
for IBM PC (tm) and compatibles
utilizing Microsoft QuickC (tm)
Copyright (c) 1991, Ted A. Campbell
Bywater Software
P. O. Box 4023
Duke Station
Durham, NC 27706
email: tcamp@hercules.acpub.duke.edu
Copyright and Permissions Information:
All U.S. and international copyrights are claimed by the
author. The author grants permission to use this code
and software based on it under the following conditions:
(a) in general, the code and software based upon it may be
used by individuals and by non-profit organizations; (b) it
may also be utilized by governmental agencies in any country,
with the exception of military agencies; (c) the code and/or
software based upon it may not be sold for a profit without
an explicit and specific permission from the author, except
that a minimal fee may be charged for media on which it is
copied, and for copying and handling; (d) the code must be
distributed in the form in which it has been released by the
author; and (e) the code and software based upon it may not
be used for illegal activities.
****************************************************************/
#include "stdio.h"
#include "dos.h"
#include "graph.h"
#include "bw.h"
#include "gr.h"
#include "malloc.h"
/*#define DEBUG */ /* Include Debugging info */
#define SET_MONOVGA FALSE
#define CHECK_PARAMS TRUE
#define LINE_BLIT TRUE
#define SIGNON FALSE
#define DEF_LINE FALSE
#define DEF_RECTANGLE FALSE
#define DEF_CIRCLE FALSE
#define HMP_RATIO 8 /* Horizontal Mickey/Pixel Ratio */
#define VMP_RATIO 16 /* Vertical Mickey/Pixel Ratio */
#define ACC 30
#define IMAGES 64
int gr_screens;
int gr_colors;
int gr_pxsize;
int gr_pysize;
int gr_ismouse;
int gr_clipping = TRUE;
int gr_blitting;
int gr_saving = TRUE;
struct gr_window *ibm_window; /* structure for window info */
int ibm_px; /* relative size of pixel, x axis */
int ibm_py; /* relative size of pixel, y axis */
int ibm_vmode; /* video mode for IBM equipment */
int ibm_imode; /* initial video mode */
int ibm_ishidden = FALSE; /* boolean: is display "hidden" */
struct videoconfig
ibm_vc; /* internal structure for video configuration */
int msm_exist = FALSE; /* boolean: is there a mouse? */
long miaddr; /* mouse interupt routine address */
union REGS ibm_registers; /* cpu register for use of DOS calls */
struct SREGS segreg; /* cpu segment registers */
static int msm_buttons; /* number of buttons on the mouse */
char far *hgc_location; /* location to change for Hercules */
static int msm_oldbut; /* previous state of mouse buttons */
static int msm_showcounter; /* keep track of mouse show status */
static int m_col, m_row; /* current column, row */
static int m_but; /* right button depressed */
char fontfile[12] = "*.fon";
char *ibm_images[ IMAGES ]; /* array of pointers to image buffers */
#if LINE_BLIT
char far *xfr_mem;
#else
char huge *xfr_mem;
#endif
unsigned char fs[ 20 ];
unsigned char fr[ 40 ];
struct _fontinfo fi;
/*** Define fill grids ***/
char _fill_blank[ 8 ] = { 0, 0, 0, 0, 0, 0, 0, 0 };
char _fill_grid[ 8 ] = { 170, 85, 170, 85, 170, 85, 170, 85 };
char _fill_full[ 8 ] = { 255, 255, 255, 255, 255, 255, 255, 255 };
char _fill_hatch[ 8 ] = { 17, 255, 68, 68, 68, 255, 17, 17 };
/****************************************************************
gr_init()
****************************************************************/
gr_init( window, font_path )
struct gr_window *window;
char *font_path;
{
int font_ret;
static char ff[ 64 ];
register int i;
ibm_window = window;
/* Set font */
if ( font_path != NULL )
{
sprintf( ff, "%s%s", font_path, fontfile );
}
else
{
strcpy( ff, fontfile );
}
if ( ( font_ret = _registerfonts( ff ) ) <= 0 )
{
strcpy ( ff, "../../fonts" );
if ( ( font_ret = _registerfonts( ff ) ) <= 0 )
{
fprintf( stderr, "Can't find font files (path: %s).\n", ff );
exit( 0 );
}
}
/* Get the video configuration to learn about hardware */
_getvideoconfig( &ibm_vc );
ibm_imode = ibm_vc.mode;
switch( ibm_vc.adapter )
{
case _HGC:
ibm_vmode = _HERCMONO;
ibm_px = 30;
ibm_py = 45;
break;
case _CGA:
case _OCGA:
ibm_vmode = _HRESBW;
ibm_px = 29;
ibm_py = 69;
break;
case _VGA:
case _OVGA:
case _MCGA:
case _EGA:
case _OEGA:
ibm_vmode = _ERESCOLOR;
#ifdef OLD_DEBUG
fprintf( stderr, "VGA: monitor is %d \n", ibm_vc.adapter );
getchar();
#endif
ibm_px = 40;
ibm_py = 50;
break;
default:
printf( "An appropriate video mode could not be located\n" );
exit( 0 );
break;
}
/* If there is a mouse, initialize it now */
msm_init();
/* set the video mode */
if ( ibm_imode != ibm_vmode )
{
_setvideomode( ibm_vmode );
#ifdef OLD_DEBUG
fprintf( stderr, "INIT....." );
getchar();
#endif
}
else
{
#ifdef OLD_DEBUG
fprintf( stderr, "No need to initialize....." );
getchar();
#endif
}
/* Get the video configuration again */
_getvideoconfig( &ibm_vc );
/* allocate transfer memory area */
#if LINE_BLIT
if ( ( xfr_mem = malloc( (size_t) _imagesize( 0, 0,
ibm_vc.numxpixels, 1 ) )) == NULL )
#else
if ( ( xfr_mem
= halloc( (long) 1, (size_t) _imagesize( 0, ibm_vc.numypixels,
ibm_vc.numxpixels, 0 ) )) == NULL )
#endif
{
gr_deinit();
fprintf( stderr,
"gr: failed to allocate memory for transfer buffer\n" );
exit( 0 );
}
/* Reset mouse cursor lines + columns */
if ( msm_exist == TRUE )
{
#ifdef WHYDOTHIS
msm_position( 0, 0 );
#endif
msm_showcounter = -1;
msm_show();
gr_ismouse = TRUE;
#ifdef OLD_DEBUG
fprintf( stderr, "yes, virginia, there is a mouse...\n" );
kb_rx();
#endif
}
else
{
gr_ismouse = FALSE;
}
#ifdef REALLYLETSDONTDOTHIS
_setactivepage ( 0 );
_clearscreen( _GCLEARSCREEN );
_setactivepage ( 1 );
_clearscreen( _GCLEARSCREEN );
#endif
_setactivepage ( 0 );
_setvisualpage ( 0 );
/* Transfer video configuration information to the gr_window struct */
window->initialized = TRUE;
window->xmax = ibm_vc.numxpixels - 1;
window->ymax = ibm_vc.numypixels - 1;
gr_screens = ibm_vc.numvideopages;
if ( gr_screens > 1 )
{
gr_blitting = TRUE;
}
else
{
gr_blitting = FALSE;
}
#if SET_MONOVGA
if ( ( ibm_vmode == _ERESCOLOR ) && ( ibm_vc.adapter == _ANALOGMONO ))
{
gr_colors = 2; /* for mono VGA */
}
else
{
gr_colors = ibm_vc.numcolors;
}
#else
gr_colors = ibm_vc.numcolors;
#endif
gr_pxsize = ibm_px;
gr_pysize = ibm_py;
/* gr signon message */
#if SIGNON
printf( "Bywater Graphics Interface Standard Implementation\n" );
printf( "Copyright (c) 1990, Ted A. Campbell\n" );
switch( ibm_vmode )
{
case _HERCMONO:
printf( "Hercules (tm) " );
break;
case _HRESBW:
printf( "CGA " );
break;
case _ERESCOLOR:
printf( "EGA or VGA " );
break;
}
printf( "or compatible graphics detected\n" );
printf( "%dx%d pixels resolution in %d colors\n",
ibm_vc.numxpixels, ibm_vc.numypixels, ibm_vc.numcolors );
printf( "%d kbytes of video RAM in %d video page(s)\n",
ibm_vc.memory, ibm_vc.numvideopages );
if ( msm_exist != FALSE )
{
printf( "Mouse device detected. \n" );
}
printf( "Please wait while font is loaded...\n" );
#endif
/* set image buffer pointers to NULL */
for ( i = 0; i < IMAGES; ++i )
{
ibm_images[ i ] = NULL;
}
ibm_screen( GR_PRIMARY );
gr_font( GR_PRIMARY, F_DEFAULT, ibm_vc.numypixels / 25 );
}
/****************************************************************
gr_deinit()
****************************************************************/
gr_deinit()
{
#if LINE_BLIT
_ffree( xfr_mem );
#else
hfree( xfr_mem );
#endif
/* hide the mouse in case we are returning to a graphics-based
program that uses the mouse */
msm_hide();
/* reset video mode if necessary */
if ( ibm_vmode != ibm_imode )
{
_setvideomode( _DEFAULTMODE );
#ifdef OLD_DEBUG
fprintf( stderr, "Deinitialized....." );
getchar();
#endif
}
else
{
#ifdef OLD_DEBUG
fprintf( stderr, "No need to deinitialize....." );
getchar();
#endif
}
}
/****************************************************************
gr_cls()
****************************************************************/
gr_cls( screen )
int screen;
{
ibm_screen( screen );
if ( screen != GR_HIDDEN )
{
msm_hide();
}
_clearscreen( _GCLEARSCREEN );
if ( screen != GR_HIDDEN )
{
msm_show();
}
}
/****************************************************************
gr_pixel()
****************************************************************/
gr_pixel( screen, x, y, color )
int screen;
int x, y;
int color;
{
#if CHECK_PARAMS
if ( ( x < 0 ) || ( x > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_pixel(): x value is %d", x );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y < 0 ) || ( y > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_pixel(): y value is %d", y );
bw_error( bw_ebuf );
return BW_ERROR;
}
#endif
ibm_screen( screen );
if ( screen != GR_HIDDEN )
{
msm_hide();
}
_setcolor( ibm_color( color ) );
_setpixel( x, ibm_window->ymax - y );
if ( screen != GR_HIDDEN )
{
msm_show();
}
}
/****************************************************************
gr_line()
****************************************************************/
gr_line( screen, x1, y1, x2, y2, color, style )
int screen;
int x1, y1, x2, y2;
int color, style;
{
#if CHECK_PARAMS
if ( ( x1 < 0 ) || ( x1 > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_line(): x1 value is %d", x1 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( x2 < 0 ) || ( x2 > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_line(): x2 value is %d", x2 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y1 < 0 ) || ( y1 > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_line(): y1 value is %d", y1 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y2 < 0 ) || ( y2 > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_line(): y2 value is %d", y2 );
bw_error( bw_ebuf );
return BW_ERROR;
}
#endif
#if DEF_LINE
def_line( screen, x1, y1, x2, y2, color, style );
#else
ibm_screen( screen );
_setcolor( ibm_color( color ));
switch( style )
{
case HOLLOW:
_setlinestyle( 0 );
break;
case GRID:
case HATCH:
_setlinestyle( 85 + (256*85) );
break;
default: /* SOLID is default */
_setlinestyle( 0xffff );
break;
}
_moveto( x1, ibm_window->ymax - y1 );
if ( screen != GR_HIDDEN )
{
msm_hide();
}
_lineto( x2, ibm_window->ymax - y2 );
if ( screen != GR_HIDDEN )
{
msm_show();
}
#endif
}
/****************************************************************
gr_text()
****************************************************************/
gr_text( screen, x, y, string, foreground, background )
int screen;
int x, y;
int foreground, background;
char *string;
{
#if CHECK_PARAMS
if ( ( x < 0 ) || ( x > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_text(): x value is %d", x );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y < 0 ) || ( y > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_text(): y value is %d", y );
bw_error( bw_ebuf );
return BW_ERROR;
}
#endif
ibm_screen( screen );
_setcolor( ibm_color( background ) );
_setbkcolor( (long) ibm_color( background ) );
_setfillmask( _fill_full );
_setlinestyle( 0xffff );
if ( screen != GR_HIDDEN )
{
msm_hide();
}
_rectangle( _GFILLINTERIOR, x,
ibm_window->ymax - ( y + ibm_window->fysize ),
x + ((int) _getgtextextent( ((unsigned char far *) string ) )) + 1,
ibm_window->ymax - ( y ) );
_moveto( x, ibm_window->ymax - ( y + ibm_window->fysize ) );
_setcolor( ibm_color( foreground ) );
_outgtext( string );
if ( screen != GR_HIDDEN )
{
msm_show();
}
}
/****************************************************************
gr_strlen()
****************************************************************/
unsigned int
gr_strlen( string )
char *string;
{
int r;
r = (unsigned int) _getgtextextent( ((unsigned char far *) string ) );
#ifdef DEBUG
if ( r < 0 )
{
sprintf( bw_ebuf, "_getgtextent() returned error, string [%s]",
string );
bw_error( bw_ebuf );
}
#endif
return r;
}
/****************************************************************
gr_rectangle()
****************************************************************/
gr_rectangle( screen, x1, y1, x2, y2, color, style )
int screen;
int x1, y1, x2, y2;
int color, style;
{
static short _control;
char *_fill_interior;
#if CHECK_PARAMS
if ( ( x1 < 0 ) || ( x1 > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_rectangle(): x1 value is %d", x1 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( x2 < 0 ) || ( x2 > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_rectangle(): x2 value is %d", x2 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y1 < 0 ) || ( y1 > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_rectangle(): y1 value is %d", y1 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y2 < 0 ) || ( y2 > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_rectangle(): y2 value is %d", y2 );
bw_error( bw_ebuf );
return BW_ERROR;
}
#endif
#if DEF_RECTANGLE
def_rectangle( screen, x1, y1, x2, y2, color, style );
#else
ibm_screen( screen );
switch( style )
{
case 0:
_fill_interior = _fill_blank;
break;
case 2:
_fill_interior = _fill_grid;
break;
case 3:
_fill_interior = _fill_hatch;
break;
default:
_fill_interior = _fill_full;
break;
}
if ( style == HOLLOW )
{
_control = _GBORDER;
}
else
{
_control = _GFILLINTERIOR;
}
_setcolor( ibm_color( color ) );
_setfillmask( _fill_interior );
if ( screen != GR_HIDDEN )
{
msm_hide();
}
_rectangle( _control, x1,
ibm_window->ymax - y1,
x2,
ibm_window->ymax - y2 );
if ( screen != GR_HIDDEN )
{
msm_show();
}
#endif
}
/****************************************************************
gr_circle()
****************************************************************/
gr_circle( screen, x, y, radius, color, style )
int screen;
int x, y, radius;
int color, style;
{
register int xradius;
static short _control;
char *_fill_interior;
#if CHECK_PARAMS
if ( ( x < 0 ) || ( x > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_circle(): x value is %d", x );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y < 0 ) || ( y > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_circle(): y value is %d", y );
bw_error( bw_ebuf );
return BW_ERROR;
}
#endif
#if DEF_CIRCLE
def_circle( screen, x, y, radius, color, style );
#else
ibm_screen( screen );
xradius = ( radius * gr_pysize ) / gr_pxsize;
switch( style )
{
case 0:
_fill_interior = _fill_blank;
break;
case 2:
_fill_interior = _fill_grid;
break;
case 3:
_fill_interior = _fill_hatch;
break;
default:
_fill_interior = _fill_full;
break;
}
if ( style == HOLLOW )
{
_control = _GBORDER;
}
else
{
_control = _GFILLINTERIOR;
}
_setcolor( ibm_color( color ) );
_setfillmask( _fill_interior );
if ( screen != GR_HIDDEN )
{
msm_hide();
}
_ellipse( _control, x - xradius,
ibm_window->ymax - ( y + radius),
x + xradius,
ibm_window->ymax - ( y - radius ));
if ( screen != GR_HIDDEN )
{
msm_show();
}
#endif
}
/****************************************************************
gr_ellipse()
****************************************************************/
gr_ellipse( screen, x, y, x_radius, y_radius, mode, color, style )
int screen;
int x, y, x_radius, y_radius;
int mode, color, style;
{
}
/****************************************************************
gr_clip()
****************************************************************/
gr_clip( screen, mode, x1, y1, x2, y2 )
int screen;
int mode;
int x1, y1, x2, y2;
{
#if CHECK_PARAMS
if ( ( x1 < 0 ) || ( x1 > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_clip(): x1 value is %d", x1 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( x2 < 0 ) || ( x2 > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_clip(): x2 value is %d", x2 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y1 < 0 ) || ( y1 > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_clip(): y1 value is %d", y1 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y2 < 0 ) || ( y2 > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_clip(): y2 value is %d", y2 );
bw_error( bw_ebuf );
return BW_ERROR;
}
#endif
ibm_screen( screen );
if ( mode == FALSE )
{
_setcliprgn( 0, 0, ibm_window->xmax - 1,
ibm_window->ymax - 1 );
ibm_window->clipping = FALSE;
return TRUE;
}
else
{
_setcliprgn( x1, ibm_window->ymax - y2,
x2, ibm_window->ymax - y1 );
ibm_window->clipping = TRUE;
ibm_window->cl_x1 = x1;
ibm_window->cl_y1 = y1;
ibm_window->cl_x2 = x2;
ibm_window->cl_y2 = y2;
return TRUE;
}
}
/****************************************************************
gr_font()
****************************************************************/
gr_font( screen, type, rq_height )
int screen;
int type, rq_height;
{
static char fs[ 48 ];
static int current_type = 0;
static int current_height = 0;
static struct _fontinfo fi;
int x;
ibm_screen( screen );
if ( ( current_type == type ) && ( current_height == rq_height ) )
{
return BW_ERROR;
}
/* first try a bit-mapped (raster-mapped) font */
sprintf( fs, "h%dw%dbr", rq_height, ( rq_height * 2 ) / 3 );
x = _setfont( fs );
_getfontinfo( &fi );
ibm_window->fysize = fi.pixheight;
ibm_window->fxsize = fi.avgwidth;
/* if this fails ( greater than 5 pixels different than request),
then try a vector font */
if ( abs( fi.pixheight - rq_height ) > 3 )
{
sprintf( fs, "h%dw%dbv", rq_height, ( rq_height * 2 ) / 3 );
x = _setfont( fs );
_getfontinfo( &fi );
ibm_window->fysize = rq_height;
ibm_window->fxsize = ( rq_height * 2 ) / 3;
}
#ifdef OLD_DEBUG
printf( "Request for font: %s\n", fs );
printf( "_setfont() returned: %d\n", x );
printf( "fontinfo: Height, %d Width, %d Ascent %d \n",
fi.pixheight,
fi.avgwidth, fi.ascent );
getch();
#endif
}
/****************************************************************
gr_blit()
****************************************************************/
gr_blit( src, dst, x1, y1, x2, y2 )
int src, dst;
int x1, y1, x2, y2;
{
#if LINE_BLIT
register int l;
#endif
#if CHECK_PARAMS
if ( ( x1 < 0 ) || ( x1 > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_blit(): x1 value is %d", x1 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( x2 < 0 ) || ( x2 > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_blit(): x2 value is %d", x2 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y1 < 0 ) || ( y1 > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_blit(): y1 value is %d", y1 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y2 < 0 ) || ( y2 > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_blit(): y2 value is %d", y2 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( src == dst )
{
sprintf( bw_ebuf, "[pr:] gr_blit(): src == dst" );
bw_error( bw_ebuf );
return BW_ERROR;
}
#endif
if ( ibm_vc.numvideopages > 1 )
{
msm_hide();
/* if the area is the entire screen, use fast blit routine */
if ( ( ( x2 - x1 ) == ibm_window->xmax )
&& ( ( y2 - y1 ) == ibm_window->ymax ))
{
#ifdef OLD_DEBUG
fprintf( stderr, "This is the fast blit routine. \n" );
getch();
#endif
if ( src == GR_PRIMARY )
{
if ( ibm_vmode == _HERCMONO )
{
movedata( (unsigned int) 0xb000, /* source segment */
(unsigned int) 0x0000, /* source offset */
(unsigned int) 0xb800, /* dest segment */
(unsigned int) 0x0000, /* dest offset */
(unsigned) 0x8000 ); /* number bytes */
}
else if ( ibm_vmode == _ERESCOLOR )
{
outp(0x3ce, 0x05); /* Mode register select */
outp(0x3cf, 0x01); /* Select write mode 1 */
outp(0x3ce, 0x03); /* Merge mode */
outp(0x3cf, 0x00); /* Replace mode */
outp(0x3ce, 0x03); /* Bit Mask register */
outp(0x3cf, 0xff); /* Select all bits */
movedata( 0xA000, 0x0000, 0xA800, 0x0000, 0x8000 );
}
}
else
{
if ( ibm_vmode == _HERCMONO )
{
movedata( (unsigned int) 0xb800,
(unsigned int) 0x0000,
(unsigned int) 0xb000,
(unsigned int) 0x0000,
(unsigned) 0x8000 );
}
if ( ibm_vmode == _ERESCOLOR )
{
outp(0x3ce, 0x05); /* Mode register select */
outp(0x3cf, 0x01); /* Select write mode 1 */
outp(0x3ce, 0x03); /* Merge mode */
outp(0x3cf, 0x00); /* Replace mode */
outp(0x3ce, 0x03); /* Bit Mask register */
outp(0x3cf, 0xff); /* Select all bits */
movedata( 0xA800, 0x0000, 0xA000, 0x0000, 0x8000 );
}
}
}
/* The area is not the complete screen; blit only part of it */
else
{
#ifdef OLD_DEBUG
fprintf( stderr, "DEBUG: imsize will be %ld bytes \n",
_imagesize( x1, y2, x2, y1 ) );
getch();
#endif
#if LINE_BLIT
for ( l = y2; l >= y1; --l )
{
ibm_screen( src );
_getimage( x1, ibm_window->ymax - l, x2, ibm_window->ymax - l,
xfr_mem );
ibm_screen( dst );
_putimage( x1, ibm_window->ymax - l, xfr_mem, _GPSET );
}
#else
ibm_screen( src );
_getimage( x1, ibm_window->ymax - y2, x2, ibm_window->ymax - y1,
xfr_mem );
ibm_screen( dst );
_putimage( x1, ibm_window->ymax - y2, xfr_mem, _GPSET );
#endif
}
}
msm_show();
return TRUE;
}
/****************************************************************
gr_imsave()
****************************************************************/
gr_imsave( screen, mode, x1, y1, x2, y2, image )
int screen;
int mode, x1, y1, x2, y2;
int *image;
{
register int r;
int carry_on;
#if CHECK_PARAMS
if ( ( x1 < 0 ) || ( x1 > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_save(): x1 value is %d", x1 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( x2 < 0 ) || ( x2 > ibm_window->xmax ))
{
sprintf( bw_ebuf, "[pr:] gr_save(): x2 value is %d", x2 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y1 < 0 ) || ( y1 > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_save(): y1 value is %d", y1 );
bw_error( bw_ebuf );
return BW_ERROR;
}
if ( ( y2 < 0 ) || ( y2 > ibm_window->ymax ))
{
sprintf( bw_ebuf, "[pr:] gr_save(): y2 value is %d", y2 );
bw_error( bw_ebuf );
return BW_ERROR;
}
#endif
ibm_screen( screen );
msm_hide();
switch ( mode )
{
case TRUE: /* TRUE = SAVE image */
#ifdef OLD_DEBUG
printf( "DEBUG: saving screen %d, %d %d %d %d\n", screen, x1, y1,
x2, y2 );
getch();
#endif
/* find an available buffer */
carry_on = TRUE;
r = 0;
while( ( carry_on == TRUE ) && ( r < IMAGES ) )
{
if ( ibm_images[ r ] == NULL )
{
carry_on = FALSE;
}
else
{
++r;
}
}
if ( r >= IMAGES )
{
bw_error( "No more slots for image storage" );
return FALSE;
}
*image = r;
/* get memory */
if ( ( ibm_images[ *image ] = malloc( (size_t) _imagesize(
x1, ibm_window->ymax - y2,
x2, ibm_window->ymax - y1 ) ) ) == NULL )
{
bw_error( "Out of memory to store image" );
return FALSE;
}
/* save the image */
_getimage( x1, ( ibm_window->ymax ) - y2, x2,
( ibm_window->ymax ) - y1,
ibm_images[ *image ] );
break;
case FALSE: /* FALSE = RESTORE image */
#ifdef OLD_DEBUG
printf( "DEBUG: restoring screen %d, %d %d %d %d\n", screen,
x1, y1, x2, y2 );
getch();
#endif
#ifdef DEBUG
if ( ibm_images[ *image ] == NULL )
{
bw_error( "gr_imsave(): NULL image requested" );
return FALSE;
}
#endif
_putimage( x1, ibm_window->ymax - y2, ibm_images[ *image ], _GPSET );
break;
default:
#ifdef DEBUG
bw_error( "[pr:] gr_save(): incorrect mode" );
#endif
msm_show();
return BW_ERROR;
break;
}
msm_show();
}
/****************************************************************
gr_imfree()
****************************************************************/
gr_imfree( image )
int image;
{
#ifdef DEBUG
if ( ibm_images[ image ] == NULL )
{
bw_error( "gr_imfree(): NULL image requested" );
return FALSE;
}
#endif
free( ibm_images[ image ] );
ibm_images[ image ] = NULL;
}
/****************************************************************
gr_mouse()
****************************************************************/
gr_mouse( mode, x, y, buttons )
int mode;
int *x, *y;
int *buttons;
{
static int m_pending = FALSE, y_pos = 0, x_pos = 0;
switch( mode )
{
case HIDE:
msm_hide();
break;
case SHOW:
msm_show();
break;
case POSITION:
msm_hide();
msm_position( ibm_window->ymax - *y, *x );
msm_show();
break;
case STATUS:
case SAMPLE:
if ( m_pending == TRUE )
{
return TRUE;
}
if ( msm_read() == TRUE )
{
x_pos = *x = m_col;
y_pos = *y = m_row;
m_pending = TRUE;
return TRUE;
}
else
{
x_pos = *x = m_col;
y_pos = *y = m_row;
return BW_ERROR;
}
break;
case WAIT:
if ( m_pending == TRUE )
{
m_pending = FALSE;
*x = x_pos;
*y = y_pos;
return TRUE;
}
while( msm_read() == FALSE )
{
;
}
*x = x_pos = m_col;
*y = y_pos = m_row;
return TRUE;
break;
default:
break;
}
}
/****************************************************************
ibm_ IBM PC (tm) specific routines
****************************************************************/
ibm_screen( screen )
int screen;
{
static int x_screen = 599;
#if CHECK_PARAMS
if ( ( screen < 0 ) || ( screen > GR_HIDDEN ))
{
sprintf( bw_ebuf, "[pr:] ibm_screen(): incorrect screen number %d",
screen );
bw_error( bw_ebuf );
}
#endif
if ( screen != x_screen )
{
_setactivepage( screen );
x_screen = screen;
}
}
ibm_color( color )
int color;
{
switch( color )
{
case 0:
return 0;
case 1:
return 15;
case 2:
return 12;
case 3:
return 10;
case 4:
return 9;
case 5:
return 14;
case 6:
return 11;
case 7:
return 13;
case 8:
return 0;
case 9:
return 15;
case 10:
return 4;
case 11:
return 2;
case 12:
return 1;
case 13:
return 5;
case 14:
return 3;
case 15:
return 6;
default:
return 1;
}
}
/****************************************************************
msm_ Microsoft Mouse Routines
****************************************************************/
msm_init()
{
/* if the video card is hercules, set the appropriate location */
if ( ibm_vmode == _HERCMONO )
{
#ifdef OLD_DEBUG
fprintf( stderr, "Hercules graphics mouse implementation.\n" );
getchar();
#endif
hgc_location = (char far *) 0x00400049;
*hgc_location = 6; /* use 5 for HGC CRT page 1 */
}
/* check if the mouse driver exists first */
ibm_registers.x.ax = 0x3533; /* look at the interrupt 33 address */
int86x( 0x21, &ibm_registers, &ibm_registers, &segreg);
miaddr = (( (long) segreg.es) << 16) + (long) ibm_registers.x.bx;
if ( miaddr == 0 || *(char *) miaddr == 0xcf)
{
msm_exist = FALSE;
return BW_ERROR;
}
/* and then check for the mouse itself */
ibm_registers.x.ax = 0; /* mouse status flag */
int86( 0x33, &ibm_registers, &ibm_registers); /* check for the mouse interupt */
msm_exist = (ibm_registers.x.ax != 0);
msm_buttons = ibm_registers.x.bx;
if ( msm_exist == FALSE)
{
#ifdef OLD_DEBUG
fprintf( stderr, "Found mouse driver, but no mouse\n" );
getchar();
#endif
return BW_ERROR;
}
/* Set minimum/maximum lines, columns */
switch ( ibm_vmode )
{
case _HERCMONO:
msm_bounds( 347, 719 );
break;
case _HRESBW:
msm_bounds( 199, 639 );
break;
case _ERESCOLOR:
msm_bounds( 349, 639 );
break;
default:
#ifdef DEBUG
fprintf( stderr, "Unknown video mode in mouse initialization <%d>\n", ibm_vmode );
getchar();
#endif
break;
}
return TRUE;
}
msm_bounds( lines, columns )
int lines, columns;
{
ibm_registers.x.ax = 7; /* set min/max horizontal cursor position */
ibm_registers.x.cx = 0; /* start at 0 */
ibm_registers.x.dx = columns - 1;
int86( 0x33, &ibm_registers, &ibm_registers);
ibm_registers.x.ax = 8; /* set min/max vertical cursor position */
ibm_registers.x.cx = 0; /* start at 0 */
ibm_registers.x.dx = lines - 1; /* end at the end */
int86( 0x33, &ibm_registers, &ibm_registers);
}
msm_show()
{
#ifdef OLD_DEBUG
fprintf( stderr, "+" );
#endif
while( msm_showcounter < 0 )
{
ibm_registers.x.ax = 1; /* show cursor */
int86( 0x33, &ibm_registers, &ibm_registers);
++msm_showcounter;
}
}
msm_hide()
{
#ifdef OLD_DEBUG
fprintf( stderr, "-" );
#endif
while( msm_showcounter >= 0 )
{
ibm_registers.x.ax = 2; /* hide cursor */
int86( 0x33, &ibm_registers, &ibm_registers);
--msm_showcounter;
}
}
msm_position( line, column )
{
ibm_registers.x.ax = 4; /* set mouse cursor position */
ibm_registers.x.cx = column;
ibm_registers.x.dx = line;
int86( 0x33, &ibm_registers, &ibm_registers);
}
msm_read()
{
register int k; /* current bit/button of mouse */
register int event; /* encoded mouse event */
int newbut; /* new state of the mouse buttons */
int mousecol; /* current mouse column */
int mouserow; /* current mouse row */
int sstate; /* current shift key status */
/* check to see if any mouse buttons are different */
ibm_registers.x.ax = 3; /* Get button status and mouse position */
int86(0x33, &ibm_registers, &ibm_registers);
newbut = ibm_registers.x.bx;
#ifdef OLDSTUFF
mousecol = ibm_registers.x.cx >> 3;
mouserow = ibm_registers.x.dx >> 3;
#else
mousecol = ibm_registers.x.cx;
mouserow = ibm_registers.x.dx;
#endif
m_col = mousecol;
m_row = ( ibm_vc.numypixels - 1 ) - ( mouserow );
/* get the shift key status as well */
sstate = 0;
ibm_registers.h.ah = 2; /* return current shift status */
int86( 0x16, &ibm_registers, &ibm_registers);
sstate = ibm_registers.h.al;
for ( k = 1; k != (1 << msm_buttons); k = k<<1)
{
/* For each button on the mouse */
if ((msm_oldbut&k) != (newbut&k))
{
/* This button changed, generate an event */
msm_oldbut = newbut;
return ( TRUE );
}
}
return ( FALSE );
}